package com.jade.editor.anisotropy.node;

import java.util.ArrayList;

import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.wb.swt.SWTResourceManager;

import com.jade.editor.anisotropy.editors.AnisotropyEditor;

public class Collector {
	
	public final static int MODE_NONE = 0;
	public final static int MODE_MOVE = 1;
	public final static int MODE_CONNECT = 2;
	public final static int MODE_DISCONNECT = 3;
	public final static int MODE_ADD = 4;
	public final static int MODE_REMOVE = 5;
	
	private RGB _borderColor = new RGB(0,0,0);
	private RGB _selectionColor = new RGB(255, 0, 0);
	private RGB _connectionColor = new RGB(0, 200, 10);
	
	private ArrayList<Cortege> _clist = new ArrayList<Cortege>();
	private ArrayList<Node> _nlist = new ArrayList<Node>();
	private Composite _parent = null;
	private Node _select1 = null;
	private Node _select2 = null;
	private AnisotropyEditor _editor = null;
	
	private int _xp = 0;
	private int _yp = 0;
	private int _mode = MODE_MOVE;
	private boolean _connection = false;
	
	public Collector(Composite parent, AnisotropyEditor editor){
		_parent = parent;
		_editor = editor;
		
		_parent.addMouseMoveListener(new MouseMoveListener() {
			public void mouseMove(MouseEvent e) {
				if (_connection){
					_xp = e.x;
					_yp = e.y;
					_parent.redraw();
				}
			}
		});
	}
	
	public ArrayList<Node> getNodeList(){
		return _nlist;
	}
	
	public RGB getBorderColor(){
		return _borderColor;
	}
	
	public RGB getSelectionColor(){
		return _selectionColor;
	}
	
	public RGB getConnectionColor(){
		return _connectionColor;
	}
	
	public void setBorderColor(RGB color){
		_borderColor = color;
		for(Node n : _nlist)
			n.setColor(color);
		
	}
	
	public void setMode(int mode){
		_mode = mode;
	}
	
	public void add(int x, int y){
		if(_mode == MODE_ADD){
			Node n = new Node(_parent, this, x, y, _borderColor, _selectionColor);
			if(!checkRadius(n)){
				_nlist.add(n);
				_editor.setDirty(true);
			}
			else
				n.punish();
		}
	}
	
	public void select(Node n){
		if (_mode == MODE_MOVE){
			if(checkRadius(n))
				n.stepBack();
			_editor.setDirty(true);
		}
		
		if (_mode == MODE_CONNECT){
			if (_select1 == null){
				_select1 = n;
				_xp = n.x;
				_yp = n.y;
				_connection = true;
			}
			else if (_select2 == null && !n.equals(_select1)){
				
				_select2 = n;
				
				if (!_select1.hasBothCorteges() && !_select2.hasBothCorteges()){
					Cortege c = new Cortege(_select1, _select2);
					
					_clist.add(c);
					
					_nlist.remove(_select1);
					_nlist.remove(_select2);
					
					_select1 = null;
					_select2 = null;
					
					_parent.redraw();
					_connection = false;
					
					_editor.setDirty(true);
				}

			}
		}
		
		if(_mode == MODE_DISCONNECT){
			
			if(n.hasBothCorteges()){
				if(n.getFirstCortege().getAnotherNode(n).hasBothCorteges()){
					
					if(n.getFirstCortege().getAnotherNode(n).getFirstCortege().equals(n.getFirstCortege())){
						n.getFirstCortege().getAnotherNode(n).setCortegeFirst(null);
					}
					
					if(n.getFirstCortege().getAnotherNode(n).getSecondCortege().equals(n.getFirstCortege())){
						n.getFirstCortege().getAnotherNode(n).setCortegeSecond(null);
					}
					
					_clist.remove(n.getFirstCortege());
					n.setCortegeFirst(null);
					
				}
				else{
					_nlist.add(n.getFirstCortege().getAnotherNode(n));
					_clist.remove(n.getFirstCortege());
					n.setCortegeFirst(null);
				}
				
				if(n.getSecondCortege().getAnotherNode(n).hasBothCorteges()){
					
					if(n.getSecondCortege().getAnotherNode(n).getFirstCortege().equals(n.getSecondCortege())){
						n.getSecondCortege().getAnotherNode(n).setCortegeFirst(null);
					}
					
					if(n.getSecondCortege().getAnotherNode(n).getSecondCortege().equals(n.getSecondCortege())){
						n.getSecondCortege().getAnotherNode(n).setCortegeSecond(null);
					}
					
					_clist.remove(n.getSecondCortege());
					n.setCortegeSecond(null);
				}
				else{
					_nlist.add(n.getSecondCortege().getAnotherNode(n));
					_clist.remove(n.getSecondCortege());
					n.setCortegeSecond(null);
				}
				_nlist.add(n);
			}
			
			//------------------------------------
			if(n.hasFirstCortege()){
				if(n.getFirstCortege().getAnotherNode(n).hasBothCorteges()){
					
					if(n.getFirstCortege().getAnotherNode(n).getFirstCortege().equals(n.getFirstCortege())){
						n.getFirstCortege().getAnotherNode(n).setCortegeFirst(null);
					}
					
					if(n.getFirstCortege().getAnotherNode(n).getSecondCortege().equals(n.getFirstCortege())){
						n.getFirstCortege().getAnotherNode(n).setCortegeSecond(null);
					}
					
					_clist.remove(n.getFirstCortege());
					n.setCortegeFirst(null);
				}
				else{
					
					n.getFirstCortege().getAnotherNode(n).freeCoteges();
					
					_nlist.add(n.getFirstCortege().getAnotherNode(n));
					_clist.remove(n.getFirstCortege());
					n.setCortegeFirst(null);
				}
				_nlist.add(n);
			}
			
			
			//-------------------------------
			if(n.hasSecondCortege()){
				if(n.getSecondCortege().getAnotherNode(n).hasBothCorteges()){
					

					if(n.getSecondCortege().getAnotherNode(n).getFirstCortege().equals(n.getSecondCortege())){
						n.getSecondCortege().getAnotherNode(n).setCortegeFirst(null);
					}
					
					if(n.getSecondCortege().getAnotherNode(n).getSecondCortege().equals(n.getSecondCortege())){
						n.getSecondCortege().getAnotherNode(n).setCortegeSecond(null);
					}
					
					_clist.remove(n.getSecondCortege());
					n.setCortegeSecond(null);
				}
				else{
					
					n.getSecondCortege().getAnotherNode(n).freeCoteges();
					
					_nlist.add(n.getSecondCortege().getAnotherNode(n));
					_clist.remove(n.getSecondCortege());
					n.setCortegeSecond(null);
				}
				_nlist.add(n);
			}
			
			_editor.setDirty(true);			
		}
		
		if(_mode == MODE_REMOVE){
			
			if(n.hasBothCorteges()){
				if(n.getFirstCortege().getAnotherNode(n).hasBothCorteges()){
					
					if(n.getFirstCortege().getAnotherNode(n).getFirstCortege().equals(n.getFirstCortege())){
						n.getFirstCortege().getAnotherNode(n).setCortegeFirst(null);
					}
					
					if(n.getFirstCortege().getAnotherNode(n).getSecondCortege().equals(n.getFirstCortege())){
						n.getFirstCortege().getAnotherNode(n).setCortegeSecond(null);
					}
					
					_clist.remove(n.getFirstCortege());
					n.setCortegeFirst(null);
					
				}
				else{
					_nlist.add(n.getFirstCortege().getAnotherNode(n));
					_clist.remove(n.getFirstCortege());
					n.setCortegeFirst(null);
				}
				
				if(n.getSecondCortege().getAnotherNode(n).hasBothCorteges()){
					
					if(n.getSecondCortege().getAnotherNode(n).getFirstCortege().equals(n.getSecondCortege())){
						n.getSecondCortege().getAnotherNode(n).setCortegeFirst(null);
					}
					
					if(n.getSecondCortege().getAnotherNode(n).getSecondCortege().equals(n.getSecondCortege())){
						n.getSecondCortege().getAnotherNode(n).setCortegeSecond(null);
					}
					
					_clist.remove(n.getSecondCortege());
					n.setCortegeSecond(null);
				}
				else{
					_nlist.add(n.getSecondCortege().getAnotherNode(n));
					_clist.remove(n.getSecondCortege());
					n.setCortegeSecond(null);
				}
				
			}
			
			//------------------------------------
			if(n.hasFirstCortege()){
				if(n.getFirstCortege().getAnotherNode(n).hasBothCorteges()){
					
					if(n.getFirstCortege().getAnotherNode(n).getFirstCortege().equals(n.getFirstCortege())){
						n.getFirstCortege().getAnotherNode(n).setCortegeFirst(null);
					}
					
					if(n.getFirstCortege().getAnotherNode(n).getSecondCortege().equals(n.getFirstCortege())){
						n.getFirstCortege().getAnotherNode(n).setCortegeSecond(null);
					}
					
					_clist.remove(n.getFirstCortege());
					n.setCortegeFirst(null);
				}
				else{
					
					n.getFirstCortege().getAnotherNode(n).freeCoteges();
					
					_nlist.add(n.getFirstCortege().getAnotherNode(n));
					_clist.remove(n.getFirstCortege());
					n.setCortegeFirst(null);
				}
			}
			
			
			//-------------------------------
			if(n.hasSecondCortege()){
				if(n.getSecondCortege().getAnotherNode(n).hasBothCorteges()){
					

					if(n.getSecondCortege().getAnotherNode(n).getFirstCortege().equals(n.getSecondCortege())){
						n.getSecondCortege().getAnotherNode(n).setCortegeFirst(null);
					}
					
					if(n.getSecondCortege().getAnotherNode(n).getSecondCortege().equals(n.getSecondCortege())){
						n.getSecondCortege().getAnotherNode(n).setCortegeSecond(null);
					}
					
					_clist.remove(n.getSecondCortege());
					n.setCortegeSecond(null);
				}
				else{
					
					n.getSecondCortege().getAnotherNode(n).freeCoteges();
					
					_nlist.add(n.getSecondCortege().getAnotherNode(n));
					_clist.remove(n.getSecondCortege());
					n.setCortegeSecond(null);
				}
			}
			
			_nlist.remove(n);
			n.punish();
			_editor.setDirty(true);
		}
	}
	
	
	public void preSelect(Node n){
		if (_mode == MODE_MOVE)
			n.setAllowMove(true);
		else
			n.setAllowMove(false);
	}
	
	
	
	public void clear(){
		for(Node n : _nlist){
			n.punish();
		}
		
		for(Cortege c : _clist){
			c.getFirstNode().punish();
			c.getLastNode().punish();
		}
		_clist.clear();
		_nlist.clear();
		_parent.redraw();
		
		_editor.setDirty(true);
	}
	
	
	public void paint(GC gc){
		
		if(_connection){
			gc.setForeground(SWTResourceManager.getColor(_connectionColor));
			gc.drawLine(_select1.x, _select1.y, _xp, _yp);
		}
		
		for(Cortege c : _clist)
			c.paint(gc);
	}
	
	public void dumpData(){
		System.out.println("==================================================");
		System.out.println("==================================================");
		System.out.println("==================================================");
		System.out.println("Free Nodes count = " + _nlist.size());
		for(Node n : _nlist)
			System.out.println(n.toString());
		System.out.println();
		System.out.println("Corteges count = " + _clist.size());
		for(Cortege c : _clist){
			System.out.println(c.getFirstNode() + "   " + c.getLastNode());
		}
	}
	
	
	private boolean checkRadius(Node n1){
		double allowedDistance = 10.0;
		for (Node n : _nlist){
			if (n.equals(n1)) continue;
			double d = Math.sqrt((n.x - n1.x) * (n.x - n1.x) + (n.y - n1.y) * (n.y - n1.y));
			if (d < allowedDistance) 
				return true;
		}
		
		return false;
	}

	public void setNodeList(ArrayList<Node> nodeList) {
		_nlist = nodeList;
		
		for(Node n : _nlist){
			n.init(_parent, this, _borderColor, _selectionColor);
		}
	}

	public void setCortegeList(ArrayList<Cortege> cortegeList) {
		_clist = cortegeList;
		for(Cortege c : _clist){
			c.init(_parent, this, _borderColor, _selectionColor);
		}
		_parent.redraw();
		
	}

	public ArrayList<Cortege> getCortegeList() {
		// TODO Auto-generated method stub
		return _clist;
	}
	
	

	

}
